package chpt05;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

@FunctionalInterface
interface TestFun {
	void f1();

	boolean equals(Object o);
}

interface Validator { // 负责判断是否符合条件
	boolean isValid(Person p);
}

interface Mapper { // 负责实现类型转换
	String toStr(Person p);
}

interface Printer { // 负责输出
	void print(String p);
}

public class LambdaTest {

	public static void printArr(Person[] persons) {
		System.out.println("----------");
		for (Person person : persons) {
			System.out.println(person);
		}
	}

	public static void main(String[] args) {
		Person[] persons = new Person[6];
		persons[0] = new Person("Wang", 25);
		persons[1] = new Person("Bo", 30);
		persons[2] = new Person("Zheng", 20);
		persons[3] = new Person("Chen", 25);
		persons[4] = null;
		persons[5] = new Person(null, 25);

		/* 测试1：使用lambda表达式。对persons进行定制化排序。 */
		// lambdaTest(persons);

		/* 测试2：使用传统方法处理persons中符合条件的元素 */
		// processPersons(persons); //将person中非null且其name也非null的name值打印出来

		/* 测试3：使用接口改进的processPersons方法 */
		/*processPersons(persons, new Validator() {
			@Override
			public boolean isValid(Person p) {
				return p != null && p.getName() != null && p.getAge() > 25;
			}
		}, new Mapper() {
			@Override
			public String toStr(Person p) {
				return p.getName() + " " + p.getAge();
			}
		}, new Printer() {
			@Override
			public void print(String x) {
				System.out.println("符合条件：" + x);
			}
		});*/
		
		/* 测试4：使用lambda表达式匹配processPersons方法中的接口中相应的方法 */
		processPersons(persons, p -> p != null && p.getName() != null && p.getAge() > 25,
				p -> p.getName() + " " + p.getAge(), 
				x -> System.out.println("符合条件：" + x));

		/* 测试5：使用lambda表达式与方法引用匹配processPersons方法中的接口中相应的方法展示*/
		processPersons(persons, p -> p != null && p.getName() != null && p.getAge() > 25, 
				p -> p.getName() + " " + p.getAge(),
				System.out::println);
		
	}
	
	/**
	 * 演示：使用lambda表达式。对persons进行定制化排序。
	 * 
	 * @param persons
	 */
	private static void lambdaTest(Person[] persons) {
		// 对姓名排序
		Arrays.sort(persons, (p1, p2) -> p1.getName().compareTo(p2.getName()));
		printArr(persons);
		// 对年龄进行排序
		Arrays.sort(persons, (p1, p2) -> p1.getAge() - p2.getAge());
		printArr(persons);
		Arrays.sort(persons, (p1, p2) -> {
			int x = p1.getAge() - p2.getAge();
			if (x != 0)
				return x;
			return p2.getName().compareTo(p1.getName());
		});
		printArr(persons);
	}

	public static void processPersons(Person[] p) {
		for (Person person : p) {
			if (person != null && person.getName() != null) {
				System.out.println(person.getName());
			}
		}
	}

	/**
	 * 使用接口改进的processPersons方法
	 * @param persons
	 * @param v
	 * @param m
	 * @param p
	 */
	public static void processPersons(Person[] persons, 
			Validator v, Mapper m, Printer p) {
		for (Person person : persons) {
			if (v.isValid(person)) {
				String str = m.toStr(person);
				p.print(str);
			}
		}
	}
}
